package priv.mill.httpclient.util;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.springframework.stereotype.Component;

@Component
public class ReflectUtil {

	public Map<String,Object> array2Map(Object...objs)throws Exception{
		return entity2Map(objs);
	}
	
	
	public Map<String,Object> entity2Map(Object obj)throws Exception{
		Class<? extends Object> class1 = obj.getClass();
		if(class1.isPrimitive()) { // 基本数据类型
			throw new IllegalArgumentException("do not convert base type");
		}
		Map<String,Object> result = new HashMap<String,Object>();
		Collection<Object> objs = null;
		if(class1.isArray()) {
			objs = new ArrayList<>();
			Collections.addAll(objs, (Object[]) obj);
		}else if(obj instanceof Collection) {
			objs=(Collection<Object>) obj;
		}
		
		if(objs!=null) {
			for (Object object : objs) {
				singleEntity2Map(result,object);
			}
		}else {
			singleEntity2Map(result,obj);
		}
		return result;
		
	}

	private void singleEntity2Map(Map<String, Object> result, Object object) throws Exception {
		if(object==null)
			return;
		if(object.getClass().equals("java.lang.Object")) {
			return;
		}
		if(Map.class.isAssignableFrom(object.getClass()))
		{
			Map<Object,Object> m = (Map) object;
			for (Entry<Object, Object> element : m.entrySet()) {
				result.put(element.getKey().toString(), element.getValue());
			}
			return ;
		}
		Class<? extends Object> class1 = object.getClass();
		Method[] methods = class1.getMethods();
		for (int i = 0; i < methods.length; i++) {
			if(isGetMethod(methods[i])) {
				Object v = methods[i].invoke(object);
				String propertyName = getPropertyName(methods[i]);
				result.put(propertyName, v);
			}
		}
	}

	private String getPropertyName(Method method) {
		String name = method.getName();
		int st=0;
		if(name.startsWith("get")) {
			st=3;
		}else {
			st=2;
		}
		name = name.substring(st);
		char f = name.charAt(0);
		if(f>='A'&&f<='Z') {
			return ((char)(f+32))+name.substring(1);
		}
		return name;
	}

	private boolean isGetMethod(Method method) {
		return (method.getName().startsWith("get")
				||
				(method.getName().startsWith("is")&&method.getReturnType().equals(Boolean.class)))
				&& 
				method.getParameterTypes().length==0
				&& 
				!method.getName().equals("get")
				;
	}

	
	public static void main(String[] args) throws Exception {
		Person person = new Person("张三",18,'男');
		Map<String,Object> maps=new HashMap<>();
		maps.put("height", 1.88);
		Map<String, Object> entity2Map = new ReflectUtil().array2Map(person,new Person("李四", 33, '女'),maps);
		System.out.println(entity2Map);
	}
	
}
